
package com.epam.adnroid.training.day6.task1;

import android.app.ExpandableListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.TextView;

/**
 * Main contact manager application activity which represents a list of users
 * with their phone numbers and allows to make a call when clicking on a number.
 * 
 * @author Anton Novikov
 */
public class ContactManager extends ExpandableListActivity {

  private final String[] phoneProjection = {
      ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.NUMBER
  };

  private final String[] nameProjection = new String[] {
      ContactsContract.CommonDataKinds.Phone._ID,
      ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
  };

  private int groupIdColumnIndex;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    populateContacts();
  }

  /**
   * Receives callbacks when a group has been expanded. Used to collapse all
   * groups expanded before other than expanded now.
   * 
   * @param groupPosition position of expanding group
   */
  @Override
  public void onGroupExpand(int groupPosition) {
    ExpandableListView container = getExpandableListView();
    ExpandableListAdapter adapter = getExpandableListAdapter();
    int groupNumber = adapter.getGroupCount();
    for (int i = 0; i < groupNumber; i++) {
      if (groupPosition != i && container.isGroupExpanded(i)) {
        container.collapseGroup(i);
      }
    }
  }

  /**
   * Receives callbacks when a child has been clicked. Used to make a call to a
   * selected person.
   * 
   * @param parent The ExpandableListView where the click happened
   * @param v The view within the expandable list/ListView that was clicked
   * @param groupPosition The group position that contains the child that was
   *          clicked
   * @param childPosition The child position within the group
   * @param id The row id of the child that was clicked
   * @return True if the click was handled
   */
  @Override
  public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
      int childPosition, long id) {
    String phoneNumber = ((TextView) v).getText().toString();
    Intent intent = new Intent(Intent.ACTION_CALL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    startActivity(intent);
    return true;
  }

  /**
   * Populates list view with contacts from phone address book.
   */
  private void populateContacts() {
    // select only contacts who has a phone number.
    String selection = ContactsContract.CommonDataKinds.Phone.NUMBER + " NOT NULL";

    // sort contacts alphabetically with localization collacation.
    String sortOrder = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
        + " COLLATE LOCALIZED ASC";

    // fetch contacts and put them to list view adapter.
    Cursor resultSet = managedQuery(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
        nameProjection, selection, null, sortOrder);

    // Cache the ID column index
    groupIdColumnIndex = resultSet
        .getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone._ID);

    ContactsAdapter adapter = new ContactsAdapter(resultSet, this,
        android.R.layout.simple_expandable_list_item_1,
        android.R.layout.simple_expandable_list_item_1, new String[] {
          ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
        }, new int[] {
          android.R.id.text1
        }, new String[] {
          ContactsContract.CommonDataKinds.Phone.NUMBER
        }, new int[] {
          android.R.id.text1
        });

    // set adapter to the activity
    setListAdapter(adapter);
  }

  /**
   * The adapter class used to fetch apropriate phone number for expaded contact
   * in the list.
   * 
   * @author Anton Novikov
   */
  private class ContactsAdapter extends SimpleCursorTreeAdapter {

    public ContactsAdapter(Cursor cursor, Context context, int groupLayout, int childLayout,
        String[] groupFrom, int[] groupTo, String[] childrenFrom, int[] childrenTo) {
      super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, childrenTo);
    }

    @Override
    protected Cursor getChildrenCursor(Cursor groupCursor) {
      Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

      String selection = ContactsContract.CommonDataKinds.Phone._ID + " = ?";
      String[] selectionArg = {
        String.valueOf(groupCursor.getLong(groupIdColumnIndex))
      };

      return managedQuery(uri, phoneProjection, selection, selectionArg, null);
    }
  }
}
